package com.vizhuo.utils.match;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vizhuo.base.model.LngLat;
import com.vizhuo.client.business.match.goods.vo.GoodsVo;
import com.vizhuo.utils.DateUtil;
import com.vizhuo.utils.StringUtil;
import com.vizhuo.utils.baidu.map.BaiDuMapUtil;
import com.vizhuo.utils.term.TermManager;
import com.vizhuo.utils.term.Terms;
import com.vizhuo.utils.term.TermsCode;

/**
 * 
 * @ClassName: MatchUtil
 * @Description: 这个工具类提供撮合需要的一些方法,包含货物摘要封装,中文转换经纬度,计算两点之间的距离等
 * @author TANDP
 * @date 2015-7-10 下午2:12:42
 * 
 */
public class MatchUtil {

    private static Logger log = LoggerFactory.getLogger(MatchUtil.class);

    /**
     * 百度地图KEY
     */
    public static final String KEY_1 = "64ce9a3079dc9514e58252c43cf39976";

    public final static double PI = 3.14159265354;

    private final static double D2R = 0.017453;

    private final static double a2 = 6378137.0;

    private final static double e2 = 0.006739496742337;

    private static final double EARTH_RADIUS = 6378137;

    private static final DecimalFormat DECIMAL_FORMATS[] = { new DecimalFormat("0.00000"), new DecimalFormat("0.0000"),
            new DecimalFormat("0.000"), new DecimalFormat("0.00") };

    private static final int RANDOM_LEVEL[] = { 10, 100, 1000, 10000 };

    /**
     * 供经纬度偏移级别
     * 
     * @ClassName: DIF_LEVEL
     * @Description: TODO(这里用一句话描述这个类的作用)
     * @author TANDP
     * @date 2015-8-7 下午7:04:24
     * 
     */
    public static enum DIF_LEVEL {
        /**
         * 0-1米级别
         */
        level0("米级别", 0),
        /**
         * 0-10米内级别
         */
        level1("十米级别", 1),
        /**
         * 10-200米内级别
         */
        level2("百米级别", 2),
        /**
         * 200-1000米内级别
         */
        level3("千米级别", 3);
        private int value;

        private String name;

        DIF_LEVEL(String name, int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public void setValue(int value) {
            this.value = value;
        }
    }

    /**
     * 拼接 货物摘要 货主发货： 起始位置+吨数+货物种类，例：北京东城至山西大同5吨钢材待运
     * 
     * @param 信息部
     * @param goodsVo
     * @return
     */
    public static String getGoodsRemark(GoodsVo goodsVo) {

        return getGoodsRemark(goodsVo.getNeedCarTime(), goodsVo.getStartProvice(), goodsVo.getStartCity(),
                goodsVo.getStartCounty(), goodsVo.getEndProvice(), goodsVo.getEndCity(), goodsVo.getEndCounty(),
                goodsVo.getGoodsType(), goodsVo.getGoodsSpeciesName(), goodsVo.getGoodsLoad(), goodsVo.getGoodsSize(),
                goodsVo.getGoodsPiece());
    }

    /**
     * 拼接 货物摘要 同城发货(推送的pushText)如：用车时间+需要+车型+来承运(整点取消后面的00)！
     * 
     * @param 信息部
     * @param goodsVo
     * @return
     */
    public static String getSameCityPushText(GoodsVo goodsVo) {
        // 这里需要调整的话，不要再随便改，先确认需要车型是不是客户端传递的码，别一会传递码一会传递名称。不清楚就和luzh确定。
        log.info("####################################推送货源，用车类型码：" + goodsVo.getNeedCarType() + "; 用车类型名称："
                + TermManager.getlabel4Value(Terms.carTypeList(), goodsVo.getNeedCarType()));
        return DateUtil.date2String(DateUtil.string2Date(goodsVo.getNeedCarTimeAll()), "MM月dd日HH点mm分") + "需要"
                + TermManager.getlabel4Value(Terms.carTypeList(), goodsVo.getNeedCarType()) + "来承运";
    }

    /**
     * 拼接 同城发货取消订单中的发货方信息
     * 
     * @param
     * @param goodsVo
     * @return
     */
    public static String getSameCityPushConText(GoodsVo goodsVo) {

        return goodsVo.getShopName() + "取消了尾号为"
                + goodsVo.getGoodsId().toString().substring(7, goodsVo.getGoodsId().toString().length()) + "的订单,请确认!";
    }

    /**
     * 拼接 货物摘要 货主发货： 起始位置+吨数+货物种类，例：北京东城至山西大同5吨钢材待运
     * 
     * @param accountType
     *            账号类型:司机/信息部/货主
     * @param startProvice
     *            起点省编码
     * @param startCity
     *            起点市编码
     * @param startCounty
     *            起点区县编码
     * @param endCity
     *            终点市编码
     * @param endCounty
     *            终点区县编码
     * @param goodsLoad
     *            货物重量
     * @param goodsType
     * @param goodsSize
     *            货物提交
     * @param goodsType
     *            货物类型
     * @return
     */
    public static String getGoodsRemark(String needCardTime, String startProvice, String startCity, String startCounty,
            String endProvice, String endCity, String endCounty, String goodsType, String goodsSpeciesName,
            double goodsLoad, double goodsSize, double goodsPiece) {

        StringBuffer result = new StringBuffer();
        if (StringUtil.isNotBlank(needCardTime) && needCardTime.length() >= 10) {
            result.append(needCardTime.substring(5, 10));
        }
        // 追加起始位置信息
        if (StringUtil.isNotBlank(startCity)) {
            String cityName = Terms.areaAllMap.get(startCity);
            if ("市辖区".equals(cityName) || TermsCode.CITY_MUNICIPALITIES.contains(startProvice)) {
                result.append(Terms.areaAllMap.get(startProvice));
            } else {
                result.append(cityName);
            }
        }
        if (StringUtil.isNotBlank(startCounty)) {
            result.append(Terms.areaAllMap.get(startCounty));
        }
        if (StringUtil.isNotBlank(endCity) || StringUtil.isNotBlank(endCity)) {
            result.append("至");
        }
        if (StringUtil.isNotBlank(endCity)) {

            String endCityName = Terms.areaAllMap.get(endCity);
            if ("市辖区".equals(endCityName) || TermsCode.CITY_MUNICIPALITIES.contains(endProvice)) {
                result.append(Terms.areaAllMap.get(endProvice));
            } else {
                result.append(endCityName);
            }

        }
        if (StringUtil.isNotBlank(endCounty)) {
            result.append(Terms.areaAllMap.get(endCounty));
        }
        String goodsLoadStr = "";
        String goodsSizeStr = "";
        String goodsPieceStr = "";
        if (goodsLoad == (int) goodsLoad) {
            goodsLoadStr = String.valueOf((int) goodsLoad);
        } else {
            goodsLoadStr = String.valueOf(goodsLoad);
        }
        if (goodsSize == (int) goodsSize) {
            goodsSizeStr = String.valueOf((int) goodsSize);
        } else {
            goodsSizeStr = String.valueOf(goodsSize);
        }
        if (goodsPiece == (int) goodsPiece) {
            goodsPieceStr = String.valueOf((int) goodsPiece);
        } else {
            goodsPieceStr = String.valueOf(goodsPiece);
        }
        if (!"0".equals(goodsLoadStr)) {
            result.append(goodsLoadStr + "吨");
        }
        if (!"0".equals(goodsSizeStr)) {
            result.append(goodsSizeStr + "立方");
        }
        if (!"0".equals(goodsPieceStr)) {
            result.append(goodsPieceStr + "件");
        }
        // if (StringUtil.isNotBlank(goodsType)) {
        // result.append(TermManager.getlabel4Value(Terms.goodsTypeList(),
        // goodsType));
        // }

        result.append(goodsSpeciesName);
        // result.append("待运");
        return result.toString();
    }


    /**
     * 中午地址转换成经纬度 返回百度地图经纬度
     * 
     * @param proviceName
     *            省
     * @param cityName
     *            市
     * @param countyName
     *            区
     * @param address
     *            详细地址
     * @return
     */
    public static LngLat addrToLngLat(String proviceName, String cityName, String countyName, String address) {

        LngLat lngLat = new LngLat();

        proviceName = proviceName == null ? "" : proviceName;
        cityName = cityName == null ? "" : cityName;
        countyName = countyName == null ? "" : countyName;
        address = address == null ? "" : address;

        // 系统简化名称发现定位错误，如：新疆吐鲁番 定位到北京的一个叫“新疆吐鲁番”的地方。古转换为标准的地址
        proviceName = proviceName.equals("新疆") ? "新疆维吾尔自治区" : proviceName;

        Map<String, String> map = getGeocoderLatitude(proviceName + cityName + countyName + address);
        if (map != null) {
            lngLat.setLng(map.get("lng"));
            lngLat.setLat(map.get("lat"));
        }
        return lngLat;
    }

    /**
     * 中午地址转换成经纬度 返回百度地图经纬度
     * 
     * @param proviceNo
     *            省编码
     * @param cityNo
     *            市编码
     * @param countyNo
     *            区编码
     * @param address
     *            详细地址
     * @return
     */
    public static LngLat areaNoToLngLat(String proviceNo, String cityNo, String countyNo, String address) {

        return addrToLngLat(Terms.areaAllMap.get(proviceNo), Terms.areaAllMap.get(cityNo),
                Terms.areaAllMap.get(countyNo), address);
    }

    /**
     * 返回输入地址的经纬度坐标 key lng(经度),lat(纬度)
     */
    public static Map<String, String> getGeocoderLatitude(String address) {
        if (StringUtil.isBlank(address)) {
            return null;
        }
        BufferedReader in = null;
        try {
            // 将地址转换成utf-8的16进制
            address = URLEncoder.encode(address, "UTF-8");
            // 如果有代理，要设置代理，没代理可注释
            // System.setProperty("http.proxyHost","192.168.1.188");
            // System.setProperty("http.proxyPort","3128");
            URL tirc = new URL("http://api.map.baidu.com/geocoder?address=" + address + "&output=json&key=" + KEY_1);

            in = new BufferedReader(new InputStreamReader(tirc.openStream(), "UTF-8"));
            String res;
            StringBuilder sb = new StringBuilder("");
            while ((res = in.readLine()) != null) {
                sb.append(res.trim());
            }
            String str = sb.toString();
            Map<String, String> map = null;
            if (StringUtil.isNotBlank(str)) {
                int lngStart = str.indexOf("lng\":");
                int lngEnd = str.indexOf(",\"lat");
                int latEnd = str.indexOf("},\"precise");
                if (lngStart > 0 && lngEnd > 0 && latEnd > 0) {
                    String lng = str.substring(lngStart + 5, lngEnd);
                    String lat = str.substring(lngEnd + 7, latEnd);
                    map = new HashMap<String, String>();
                    map.put("lng", lng);
                    map.put("lat", lat);
                    return map;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 计算gps两点之间的距离-方式一
     * 
     * @param lng1
     * @param lat1
     * @param lng2
     * @param lat2
     * @return 单位米
     * @author tandp
     * @version 2014-5-6 上午10:34:16
     */
    public static double getDistanceFromXtoYWayOne(Double lng1, Double lat1, Double lng2, Double lat2) {
        if (lng1 == lng2 && lat1 == lat2) {
            return 0.0;
        } else {
            double fdLambda = (lng1 - lng2) * D2R;
            double fdPhi = (lat1 - lat2) * D2R;
            double fPhimean = ((lat1 + lat2) / 2.0) * D2R;
            double fTemp = 1 - e2 * (Math.pow(Math.sin(fPhimean), 2));
            double fRho = (a2 * (1 - e2)) / Math.pow(fTemp, 1.5);
            double fNu = a2 / (Math.sqrt(1 - e2 * (Math.sin(fPhimean) * Math.sin(fPhimean))));
            double fz = Math.sqrt(Math.pow(Math.sin(fdPhi / 2.0), 2) + Math.cos(lat2 * D2R) * Math.cos(lat1 * D2R)
                    * Math.pow(Math.sin(fdLambda / 2.0), 2));
            fz = 2 * Math.asin(fz);
            double fAlpha = Math.cos(lat2 * D2R) * Math.sin(fdLambda) * 1 / Math.sin(fz);
            fAlpha = Math.asin(fAlpha);
            double fR = (fRho * fNu) / ((fRho * Math.pow(Math.sin(fAlpha), 2)) + (fNu * Math.pow(Math.cos(fAlpha), 2)));
            return fz * fR;
        }
    }

    /**
     * 计算gps两点之间的距离-方式一
     * 
     * @param lng1
     * @param lat1
     * @param lng2
     * @param lat2
     * @return
     */
    public static double getDistanceFromXtoYWayOne(String lng1, String lat1, String lng2, String lat2) {

        if (StringUtil.isBlank(lng1) || "0.0".equals(lng1) || StringUtil.isBlank(lat1) || "0.0".equals(lat1)
                || StringUtil.isBlank(lng2) || "0.0".equals(lng2) || StringUtil.isBlank(lat2) || "0.0".equals(lat2)) {
            return 0.0;
        }
        return getDistanceFromXtoYWayOne(Double.parseDouble(lng1), Double.parseDouble(lng2), Double.parseDouble(lat1),
                Double.parseDouble(lat2));

    }

    /**
     * 计算gps两点之间的距离-方式二,推荐用方式一或者-方式三
     * 
     * @param lat_a
     * @param lng_a
     * @param lat_b
     * @param lng_b
     * @return
     * @author tandp
     * @version 2014-5-6 上午10:34:33
     */
    public static double getDistanceFromXtoYWayTwo(double lat_a, double lng_a, double lat_b, double lng_b) {
        double pk = (double) (180 / PI);
        double a1 = lat_a / pk;
        double a2 = lng_a / pk;
        double b1 = lat_b / pk;
        double b2 = lng_b / pk;
        double t1 = Math.cos(a1) * Math.cos(a2) * Math.cos(b1) * Math.cos(b2);
        double t2 = Math.cos(a1) * Math.sin(a2) * Math.cos(b1) * Math.sin(b2);
        double t3 = Math.sin(a1) * Math.sin(b1);
        double tt = Math.acos(t1 + t2 + t3);
        return 6366000 * tt;
    }

    private static double rad(double d) {

        return d * Math.PI / 180.0;
    }

    /**
     * 根据两点间经纬度坐标（double值），计算两点间距离，单位为米-方式三 小数点后,1公里约等于10000
     * 
     * @param lng1
     * @param lat1
     * @param lng2
     * @param lat2
     * @return
     */
    public static double getDistance(double lng1, double lat1, double lng2, double lat2) {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2)
                * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        s = Math.round(s * 10000) / 10000;
        return s;
    }

    /**
     * 根据两点间经纬度坐标（double值），计算两点间距离，单位为米-方式三
     * 
     * @param lng1
     * @param lat1
     * @param lng2
     * @param lat2
     * @return
     */
    public static double getDistance(String lng1, String lat1, String lng2, String lat2) {

        if (StringUtil.isBlank(lng1) || "0.0".equals(lng1) || StringUtil.isBlank(lat1) || "0.0".equals(lat1)
                || StringUtil.isBlank(lng2) || "0.0".equals(lng2) || StringUtil.isBlank(lat2) || "0.0".equals(lat2)) {
            return 0.0;
        }
        return getDistance(Double.parseDouble(lng1), Double.parseDouble(lat1), Double.parseDouble(lng2),
                Double.parseDouble(lat2));

    }

    /**
     * 该函数处理办法:将小数部分第5位/第6位按随机数处理 处理经纬度
     * 经纬度坐标数值，不管小数度、还是度分秒（二者实质相同），都是角度数值，跟米、公里等距离单位不能进行简单折算，但可以分具体情况。比如：
     * 经度0.00001度（十万分之一度，0°0'0.036"），在赤道上对应的地球表面距离约为1米稍多，但在南北极极点上，则是0米。 　　
     * 纬度0.00001度在地球表面任意地方对应的地球表面距离都是大约1米稍多。
     * 
     * @param param
     * @return
     */
    public static double handleLngLat(double param, DIF_LEVEL difLevel) {
        if (param == 0) {
            return 0;
        }
        double result = param;
        // 随机数
        int _index = 2;
        if (difLevel != null) {
            _index = difLevel.getValue();
        }
        Double dRandom = new Double(RANDOM_LEVEL[_index] * Math.random());
        Integer iRandom = new Integer(dRandom.intValue());
        // System.out.println(iRandom);
        DecimalFormat df = DECIMAL_FORMATS[_index];
        result = Double.parseDouble(df.format(param) + iRandom);
        return result;
    }

    /**
     * 该函数处理办法:将小数部分第5位/第6位按随机数处理 处理经纬度
     * 
     * @param param
     * @return
     */
    public static String handleLngLat(String param, DIF_LEVEL defLevel) {
        if (StringUtil.isBlank(param) || "0.0".equals(param) || "0".equals(param)) {
            return "0.0";
        }
        return String.valueOf(handleLngLat(Double.parseDouble(param), defLevel));
    }

    /**
     * 性能测试结果:1000次,共耗时:0.004秒 准确度测试结果:
     * 
     * @param args
     */
    public static void main(String[] args) {
        // LngLat addrToLngLat = addrToLngLat("11", "1101", "110101", "八里桥");
        // LngLat addrToLngLat = areaNoToLngLat("11", "1101", "110101", "八里桥");
        // System.out.println(addrToLngLat.getLng() + "," +
        double startLng = 87.565742;
        double startLat = 43.840208;

        // double endLng = 89.181595;
        // double endLat = 42.96047;

        double endLng = 116.519435;
        double endLat = 39.683117;
        // LngLat lngLatStart = MatchUtil.areaNoToLngLat("65", "6501",
        // "", "");
        // LngLat lngLatEnd = MatchUtil.areaNoToLngLat("65", "6521",
        // "", "");

        // LngLat lngLatEnd = MatchUtil.areaNoToLngLat("65", "6501", "", "");
        // System.out.println("bb:" + lngLatEnd.getAddress());
        // System.out.println("lat:" + lngLatEnd.getLat());
        // System.out.println("lng:" + lngLatEnd.getLng());
        System.out.println("aa" + getDistance(startLng, startLat, endLng, endLat));
        System.out.println("偏移经度测试-------------");
        System.out.println(getDistance(116.999990, 39.999999, 116.999999, 39.999999));
        System.out.println(getDistance(116.999900, 39.999999, 116.999999, 39.999999));
        System.out.println(getDistance(116.999000, 39.999999, 116.999999, 39.999999));
        System.out.println(getDistance(116.990000, 39.999999, 116.999999, 39.999999));
        System.out.println(getDistance(116.900000, 39.999999, 116.999999, 39.999999));
        System.out.println(getDistance(116.099999, 39.999999, 116.999999, 39.999999));
        System.out.println("偏移纬度测试-------------");
        System.out.println(getDistance(116.999999, 39.999990, 116.999999, 39.999999));
        System.out.println(getDistance(116.999999, 39.999900, 116.999999, 39.999999));
        System.out.println(getDistance(116.999999, 39.999000, 116.999999, 39.999999));
        System.out.println(getDistance(116.999999, 39.990000, 116.999999, 39.999999));
        System.out.println("10公里以内");
        System.out.println(getDistance(116.999999, 39.900000, 116.999999, 40.000000));
        System.out.println(getDistance(116.999999, 39.900000, 116.999999, 39.999999));
        System.out.println(getDistance(116.980000, 39.980000, 116.999999, 39.999999));
        System.out.println(getDistance(116.979999, 39.970000, 116.999999, 39.999999));
        System.out.println(getDistance(116.960000, 39.960000, 116.999999, 39.999999));
        System.out.println(getDistance(116.990000, 39.950000, 116.999999, 39.999999));
        System.out.println(getDistance(116.980000, 39.940000, 116.999999, 39.999999));
        System.out.println(getDistance(116.990000, 39.930000, 116.999999, 39.999999));
        System.out.println(getDistance(116.980000, 39.920000, 116.999999, 39.999999));
        System.out.println("10公里以内");
        System.out.println(getDistance(116.555555, 39.555555, 116.555555, 39.555555));
        System.out.println(getDistance(116.555555, 39.555555, 116.555555, 39.545555));
        System.out.println(getDistance(116.555555, 39.555555, 116.555555, 39.565555));
        System.out.println(getDistance(116.555555, 39.555555, 116.555555, 39.535555));
        System.out.println(getDistance(116.555555, 39.555555, 116.555555, 39.575555));

        System.out.println("140公里以内");
        System.out.println(getDistance(116.000000, 39.000000, 116.999999, 39.999999));
        System.out.println(getDistance(116.800000, 39.800000, 116.999999, 39.999999));
        System.out.println(getDistance(116.700000, 39.70000, 116.999999, 39.999999));
        System.out.println(getDistance(116.600000, 39.6000000, 116.999999, 39.999999));
        System.out.println(getDistance(116.500000, 39.500000, 116.999999, 39.999999));
        System.out.println(getDistance(116.200000, 39.2000000, 116.999999, 39.999999));
        System.out.println(getDistance(116.100000, 39.100000, 116.999999, 39.999999));
        System.out.println("经度纬度同时偏移测试-------------");
        System.out.println(getDistance(116.999990, 39.999990, 116.999999, 39.999999));
        System.out.println(getDistance(116.999909, 39.999909, 116.999999, 39.999999));
        System.out.println(getDistance(116.999099, 39.999099, 116.999999, 39.999999));
        System.out.println(getDistance(116.990999, 39.990999, 116.999999, 39.999999));
        System.out.println(getDistance(116.900000, 39.900000, 116.999999, 39.999999));
        System.out.println(getDistance(116.955555, 39.955555, 116.999999, 39.999999));
        System.out.println(getDistance(116.099999, 39.099999, 116.999999, 39.999999));
        // addrToLngLat.getLat());
        // jltest1();
        // jltest2();
        // jltest3();
        // xntest();
        // jlcjtest();
        // testrando();// 测试随机数
        // testhandleLngLat();// 测试经纬度处理结果

    }

    private static void testhandleLngLat() {
        DecimalFormat df = new DecimalFormat("0.00");
        double lng2_1 = 116.330782;
        double lat2_1 = 39.915601;

        double lng2_2 = 112.979353;
        double lat2_2 = 28.213478;

        double lng2_3 = 116.337795;
        double lat2_3 = 39.977523;

        double lng2_4 = 126.657717;
        double lat2_4 = 45.773225;

        double lng2_5 = 116.647823;
        double lat2_5 = 39.921774;

        double lng2_6 = 113.649644;
        double lat2_6 = 34.75661;

        double result_1 = getDistance(lng2_1, lat2_1, handleLngLat(lng2_1, DIF_LEVEL.level0),
                handleLngLat(lat2_1, DIF_LEVEL.level0));
        System.out.println(result_1);

        double result_2 = getDistance(lng2_2, lat2_2, handleLngLat(lng2_2, DIF_LEVEL.level1),
                handleLngLat(lat2_2, DIF_LEVEL.level1));
        System.out.println(result_2);

        double result_3 = getDistance(lng2_3, lat2_3, handleLngLat(lng2_3, DIF_LEVEL.level2),
                handleLngLat(lat2_3, DIF_LEVEL.level2));
        System.out.println(result_3);

        double result_4 = getDistance(lng2_4, lat2_4, handleLngLat(lng2_4, DIF_LEVEL.level3),
                handleLngLat(lat2_4, DIF_LEVEL.level3));
        System.out.println(result_4);

        double result_5 = getDistance(lng2_5, lat2_5, handleLngLat(lng2_5, DIF_LEVEL.level3),
                handleLngLat(lat2_5, DIF_LEVEL.level3));
        System.out.println(result_5);

    }

    private static void testrando() {
        // TODO Auto-generated method stub
        Double dRandom = new Double(100 * Math.random());
        Integer iRandom = new Integer(dRandom.intValue());
        System.out.println(iRandom);
        DecimalFormat df = new DecimalFormat("0.0000");
        double lng1 = 116.316491;
        System.out.println(df.format(lng1));
        System.out.println(Double.parseDouble(df.format(lng1) + iRandom));
    }

    /**
     * 经度0.00001度（十万分之一度，0°0'0.036"），在赤道上对应的地球表面距离约为1米稍多，但在南北极极点上，则是0米。
     * 纬度0.00001度在地球表面任意地方对应的地球表面距离都是大约1米稍多。
     */
    private static void jlcjtest() {
        DecimalFormat df = new DecimalFormat("0.00");
        double lng1 = 116.316999;
        double lat1 = 39.913999;

        double lng2 = 116.316001;
        double lat2 = 39.913001;

        double distance = getDistanceFromXtoYWayOne(lng1, lat1, lng2, lat2);
        System.out.println("distance:" + df.format(distance));

    }

    /**
     * 测试getDistanceFromXtoYWayOne方法与百度API差距
     */
    private static void jltest1() {
        DecimalFormat df = new DecimalFormat("0.00");
        double lng2_1 = 116.330782;
        double lat2_1 = 39.915601;

        double lng2_2 = 112.979353;
        double lat2_2 = 28.213478;

        double lng2_3 = 116.337795;
        double lat2_3 = 39.977523;

        double lng2_4 = 126.657717;
        double lat2_4 = 45.773225;

        double lng2_5 = 116.647823;
        double lat2_5 = 39.921774;

        double lng2_6 = 113.649644;
        double lat2_6 = 34.75661;

        // 起点:116.316465, 39.913468,
        // 终点:116.330782,39.915601(军事博物馆),结果:1246.81,百度结果:1991.88,差距:745.08米,误差率:37.41%
        // 终点:116.34177,39.982208(知春路),结果:7932.63,百度结果:8741.42,差距:808.78米,误差率:9.25%
        // 终点:116.337795,39.977523(中关村),结果:7341.90,百度结果:8142.68,差距:800.77米,误差率:9.83%
        // 终点:终点:116.647823,39.921774(八里桥),结果:28344.95,百度结果:28857.98,差距:513.03米,误差率:1.78%
        // 终点:112.979353,28.213478(长沙),结果:1333567.02,百度结果:1335724.76,差距:2157.74米,误差率:0.16%
        double result_1 = getDistanceFromXtoYWayOne(116.316465, 39.913468, lng2_1, lat2_1);
        double result2_1 = BaiDuMapUtil.getDistance("39.913468", "116.316465", String.valueOf(lat2_1),
                String.valueOf(lng2_1));
        System.out.println("终点:" + lng2_1 + "," + lat2_1 + "(军事博物馆),结果:" + df.format(result_1) + ",百度结果:"
                + df.format(result2_1) + ",差距:" + df.format((result2_1 - result_1)) + "米" + ",误差率:"
                + df.format((result2_1 - result_1) / result2_1 * 100) + "%");

        double result_2 = getDistanceFromXtoYWayOne(116.316465, 39.913468, lng2_2, lat2_2);
        double result2_2 = BaiDuMapUtil.getDistance("39.913468", "116.316465", String.valueOf(lat2_2),
                String.valueOf(lng2_2));
        System.out.println("终点:" + lng2_2 + "," + lat2_2 + "(长沙),结果:" + df.format(result_2) + ",百度结果:"
                + df.format(result2_2) + ",差距:" + df.format((result2_2 - result_2)) + "米" + ",误差率:"
                + df.format((result2_2 - result_2) / result2_2 * 100) + "%");
        double result_3 = getDistanceFromXtoYWayOne(116.316465, 39.913468, lng2_3, lat2_3);
        double result2_3 = BaiDuMapUtil.getDistance("39.913468", "116.316465", String.valueOf(lat2_3),
                String.valueOf(lng2_3));
        System.out.println("终点:" + lng2_3 + "," + lat2_3 + "(中关村),结果:" + df.format(result_3) + ",百度结果:"
                + df.format(result2_3) + ",差距:" + df.format((result2_3 - result_3)) + "米" + ",误差率:"
                + df.format((result2_3 - result_3) / result2_3 * 100) + "%");
        double result_4 = getDistanceFromXtoYWayOne(116.316465, 39.913468, lng2_4, lat2_4);
        double result2_4 = BaiDuMapUtil.getDistance("39.913468", "116.316465", String.valueOf(lat2_4),
                String.valueOf(lng2_4));
        System.out.println("终点:" + lng2_4 + "," + lat2_4 + "(哈尔滨市),结果:" + df.format(result_4) + ",百度结果:"
                + df.format(result2_4) + ",差距:" + df.format((result2_4 - result_4)) + "米" + ",误差率:"
                + df.format((result2_4 - result_4) / result2_4 * 100) + "%");

        double result_5 = getDistanceFromXtoYWayOne(116.316465, 39.913468, lng2_5, lat2_5);
        double result2_5 = BaiDuMapUtil.getDistance("39.913468", "116.316465", String.valueOf(lat2_5),
                String.valueOf(lng2_5));
        System.out.println("终点:" + lng2_5 + "," + lat2_5 + "(八里桥),结果:" + df.format(result_5) + ",百度结果:"
                + df.format(result2_5) + ",差距:" + df.format((result2_5 - result_5)) + "米" + ",误差率:"
                + df.format((result2_5 - result_5) / result2_5 * 100) + "%");

        double result_6 = getDistanceFromXtoYWayOne(116.316465, 39.913468, lng2_6, lat2_6);
        double result2_6 = BaiDuMapUtil.getDistance("39.913468", "116.316465", String.valueOf(lat2_6),
                String.valueOf(lng2_6));
        System.out.println("终点:" + lng2_6 + "," + lat2_6 + "(郑州),结果:" + df.format(result_6) + ",百度结果:"
                + df.format(result2_6) + ",差距:" + df.format((result2_6 - result_6)) + "米" + ",误差率:"
                + df.format((result2_6 - result_6) / result2_6 * 100) + "%");

    }

    /**
     * /** 测试getDistanceFromXtoYWayTwo方法与百度API差距
     */
    private static void jltest2() {
        DecimalFormat df = new DecimalFormat("0.00");
        double lng2_1 = 116.330782;
        double lat2_1 = 39.915601;

        double lng2_2 = 112.979353;
        double lat2_2 = 28.213478;

        double lng2_3 = 116.337795;
        double lat2_3 = 39.977523;

        double lng2_4 = 116.34177;
        double lat2_4 = 39.982208;

        double lng2_5 = 116.647823;
        double lat2_5 = 39.921774;

        // 起点:116.316465, 39.913468,
        // 终点:116.330782,39.915601(军事博物馆),结果:1594.20,百度结果:1991.88,差距:397.69米,误差率:19.97%
        // 终点:112.979353,28.213478(长沙),结果:655194.96,百度结果:1335724.76,差距:680529.80米,误差率:50.95%
        // 终点:116.337795,39.977523(中关村),结果:3947.04,百度结果:8142.68,差距:4195.63米,误差率:51.53%
        // 终点:116.34177,39.982208(知春路),结果:4402.25,百度结果:8741.42,差距:4339.17米,误差率:49.64%
        // 终点:116.647823,39.921774(八里桥),结果:36818.71,百度结果:28857.98,差距:-7960.73米,误差率:-27.59%
        double result_1 = getDistanceFromXtoYWayTwo(116.316465, 39.913468, lng2_1, lat2_1);
        double result2_1 = BaiDuMapUtil.getDistance("39.913468", "116.316465", String.valueOf(lat2_1),
                String.valueOf(lng2_1));
        System.out.println("终点:" + lng2_1 + "," + lat2_1 + "(军事博物馆),结果:" + df.format(result_1) + ",百度结果:"
                + df.format(result2_1) + ",差距:" + df.format((result2_1 - result_1)) + "米" + ",误差率:"
                + df.format((result2_1 - result_1) / result2_1 * 100) + "%");

        double result_2 = getDistanceFromXtoYWayTwo(116.316465, 39.913468, lng2_2, lat2_2);
        double result2_2 = BaiDuMapUtil.getDistance("39.913468", "116.316465", String.valueOf(lat2_2),
                String.valueOf(lng2_2));
        System.out.println("终点:" + lng2_2 + "," + lat2_2 + "(长沙),结果:" + df.format(result_2) + ",百度结果:"
                + df.format(result2_2) + ",差距:" + df.format((result2_2 - result_2)) + "米" + ",误差率:"
                + df.format((result2_2 - result_2) / result2_2 * 100) + "%");
        double result_3 = getDistanceFromXtoYWayTwo(116.316465, 39.913468, lng2_3, lat2_3);
        double result2_3 = BaiDuMapUtil.getDistance("39.913468", "116.316465", String.valueOf(lat2_3),
                String.valueOf(lng2_3));
        System.out.println("终点:" + lng2_3 + "," + lat2_3 + "(中关村),结果:" + df.format(result_3) + ",百度结果:"
                + df.format(result2_3) + ",差距:" + df.format((result2_3 - result_3)) + "米" + ",误差率:"
                + df.format((result2_3 - result_3) / result2_3 * 100) + "%");
        double result_4 = getDistanceFromXtoYWayTwo(116.316465, 39.913468, lng2_4, lat2_4);
        double result2_4 = BaiDuMapUtil.getDistance("39.913468", "116.316465", String.valueOf(lat2_4),
                String.valueOf(lng2_4));
        System.out.println("终点:" + lng2_4 + "," + lat2_4 + "(知春路),结果:" + df.format(result_4) + ",百度结果:"
                + df.format(result2_4) + ",差距:" + df.format((result2_4 - result_4)) + "米" + ",误差率:"
                + df.format((result2_4 - result_4) / result2_4 * 100) + "%");
        double result_5 = getDistanceFromXtoYWayTwo(116.316465, 39.913468, lng2_5, lat2_5);
        double result2_5 = BaiDuMapUtil.getDistance("39.913468", "116.316465", String.valueOf(lat2_5),
                String.valueOf(lng2_5));
        System.out.println("终点:" + lng2_5 + "," + lat2_5 + "(八里桥),结果:" + df.format(result_5) + ",百度结果:"
                + df.format(result2_5) + ",差距:" + df.format((result2_5 - result_5)) + "米" + ",误差率:"
                + df.format((result2_5 - result_5) / result2_5 * 100) + "%");

    }

    /**
     * /** 测试getDistanceFromXtoYWayTwo方法与百度API差距
     */
    private static void jltest3() {
        DecimalFormat df = new DecimalFormat("0.00");
        double lng2_1 = 116.330782;
        double lat2_1 = 39.915601;

        double lng2_2 = 112.979353;
        double lat2_2 = 28.213478;

        double lng2_3 = 116.337795;
        double lat2_3 = 39.977523;

        double lng2_4 = 126.657717;
        double lat2_4 = 45.773225;

        double lng2_5 = 116.647823;
        double lat2_5 = 39.921774;

        double lng2_6 = 113.649644;
        double lat2_6 = 34.75661;

        // 起点:116.316465, 39.913468(复兴路29号翠微广场A座),
        // 终点:116.330782,39.915601(军事博物馆),结果:1245.00,百度结果:1991.88,差距:746.88米,误差率:37.50%
        // 终点:116.337795,39.977523(中关村),结果:7359.00,百度结果:8142.68,差距:783.68米,误差率:9.62%
        // 终点:116.647823,39.921774(八里桥),结果:28305.00,百度结果:28857.98,差距:552.98米,误差率:1.92%
        // 终点:126.657717,45.773225(哈尔滨市),结果:1065283.00,百度结果:1064946.47,差距:-336.53米,误差率:-0.03%
        // 终点:112.979353,28.213478(长沙),结果:1338005.00,百度结果:1335724.76,差距:-2280.24米,误差率:-0.17%
        // 终点:113.649644,34.75661(郑州),结果:619122.58,百度结果:619080.47,差距:-42.11米,误差率:-0.01%

        double result_1 = getDistance(116.316465, 39.913468, lng2_1, lat2_1);
        double result2_1 = BaiDuMapUtil.getDistance("39.913468", "116.316465", String.valueOf(lat2_1),
                String.valueOf(lng2_1));
        System.out.println("终点:" + lng2_1 + "," + lat2_1 + "(军事博物馆),结果:" + df.format(result_1) + ",百度结果:"
                + df.format(result2_1) + ",差距:" + df.format((result2_1 - result_1)) + "米" + ",误差率:"
                + df.format((result2_1 - result_1) / result2_1 * 100) + "%");

        double result_2 = getDistance(116.316465, 39.913468, lng2_2, lat2_2);
        double result2_2 = BaiDuMapUtil.getDistance("39.913468", "116.316465", String.valueOf(lat2_2),
                String.valueOf(lng2_2));
        System.out.println("终点:" + lng2_2 + "," + lat2_2 + "(长沙),结果:" + df.format(result_2) + ",百度结果:"
                + df.format(result2_2) + ",差距:" + df.format((result2_2 - result_2)) + "米" + ",误差率:"
                + df.format((result2_2 - result_2) / result2_2 * 100) + "%");
        double result_3 = getDistance(116.316465, 39.913468, lng2_3, lat2_3);
        double result2_3 = BaiDuMapUtil.getDistance("39.913468", "116.316465", String.valueOf(lat2_3),
                String.valueOf(lng2_3));
        System.out.println("终点:" + lng2_3 + "," + lat2_3 + "(中关村),结果:" + df.format(result_3) + ",百度结果:"
                + df.format(result2_3) + ",差距:" + df.format((result2_3 - result_3)) + "米" + ",误差率:"
                + df.format((result2_3 - result_3) / result2_3 * 100) + "%");
        double result_4 = getDistance(116.316465, 39.913468, lng2_4, lat2_4);
        double result2_4 = BaiDuMapUtil.getDistance("39.913468", "116.316465", String.valueOf(lat2_4),
                String.valueOf(lng2_4));
        System.out.println("终点:" + lng2_4 + "," + lat2_4 + "(哈尔滨市),结果:" + df.format(result_4) + ",百度结果:"
                + df.format(result2_4) + ",差距:" + df.format((result2_4 - result_4)) + "米" + ",误差率:"
                + df.format((result2_4 - result_4) / result2_4 * 100) + "%");
        double result_5 = getDistance(116.316465, 39.913468, lng2_5, lat2_5);
        double result2_5 = BaiDuMapUtil.getDistance("39.913468", "116.316465", String.valueOf(lat2_5),
                String.valueOf(lng2_5));
        System.out.println("终点:" + lng2_5 + "," + lat2_5 + "(八里桥),结果:" + df.format(result_5) + ",百度结果:"
                + df.format(result2_5) + ",差距:" + df.format((result2_5 - result_5)) + "米" + ",误差率:"
                + df.format((result2_5 - result_5) / result2_5 * 100) + "%");

        double result_6 = getDistanceFromXtoYWayOne(116.316465, 39.913468, lng2_6, lat2_6);
        double result2_6 = BaiDuMapUtil.getDistance("39.913468", "116.316465", String.valueOf(lat2_6),
                String.valueOf(lng2_6));
        System.out.println("终点:" + lng2_6 + "," + lat2_6 + "(郑州),结果:" + df.format(result_6) + ",百度结果:"
                + df.format(result2_6) + ",差距:" + df.format((result2_6 - result_6)) + "米" + ",误差率:"
                + df.format((result2_6 - result_6) / result2_6 * 100) + "%");

    }

    private static void xntest() {
        System.out.println("开始...");
        long l1 = System.currentTimeMillis();
        System.out.println(l1);
        int n = 1000;
        for (int i = 0; i < n; i++) {
            double distance = getDistanceFromXtoYWayOne(116.316465, 39.913468, 116.34177, 39.982208);
            // System.out.println(distance);

        }
        long l2 = System.currentTimeMillis();
        System.out.println(l2);
        System.out.println(n + "次,共耗时:" + (l2 - l1) / 1000.0 + "秒,平均单次耗时:" + (l2 - l1) / 1000.0 / n + "秒");
        System.out.println("结束...");
    }

    /**
     * 判断经纬度是否为空,空返回true
     * 
     * @param lng
     * @return
     */
    public static boolean isNullLnglat(String lngorlat) {
        if (StringUtil.isBlank(lngorlat) || "0".equals(lngorlat) || "0.0".equals(lngorlat)) {
            return true;
        }
        return false;
    }
}
